package com.xtravel.common.helper;

import android.os.AsyncTask;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xtravel.common.api.domain.BaseJson;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import java.util.Map;

public class HttpRequestHelper<T> {
    private static final String BASE_URL = "http://121.41.88.34/api/app/";

    public void getAsync(final String api, final Map<String, String> args, final IHttpRequestCallback callback) {
        final HttpRequestHelper<T> self = this;
        new AsyncTask<Void, Void, T>() {
            @Override
            protected T doInBackground(Void... params) {
                return self.get(api, args);
            }

            @Override
            protected void onPostExecute(T data) {
                if (callback != null)
                    callback.onDataCallBack(data);
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public T get(String api, Map<String, String> args) {
        try {
            String url = BASE_URL + api;
            String serverUrl = createUrl(url, args);
            HttpGet request = new HttpGet(serverUrl);
            if (UserContext.IsSignin()) {
                request.setHeader("token", UserContext.GetCurrentToken().getToken());
            }

            HttpResponse response = new DefaultHttpClient().execute(request);
            if (response.getStatusLine().getStatusCode() == 200)
                return parseData(response);
        } catch (Exception e) {

        }

        return null;
    }

    public void postAsync(final String api, final Map<String, String> args, final IHttpRequestCallback callback) {
        new AsyncTask<Void, Void, T>() {
            @Override
            protected T doInBackground(Void... params) {
                return post(api, args);
            }

            @Override
            protected void onPostExecute(T data) {
                if (callback != null)
                    callback.onDataCallBack(data);
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public T post(String api, Map<String, String> args) {
        T data = null;
        try {
            String url = BASE_URL + api;
            HttpPost request = new HttpPost(url);
            if (UserContext.IsSignin()) {
                request.setHeader("token", UserContext.GetCurrentToken().getToken());
            }

            Gson gson = new Gson();
            StringEntity jsonEntity = new StringEntity(gson.toJson(args), HTTP.UTF_8);
            jsonEntity.setContentType("application/json");
            request.setEntity(jsonEntity);

            HttpResponse response = new DefaultHttpClient().execute(request);
            if (response.getStatusLine().getStatusCode() < 500) {
                data = parseData(response);
            } else {
                Log.d("HttpHelper", String.format("response code:%s", response.getStatusLine().getStatusCode()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return data;
    }

    private T parseData(HttpResponse response) {
        try {
            String content = EntityUtils.toString(response.getEntity());
            BaseJson<T> json = JsonHelper.fromJson(content, new TypeToken<BaseJson<T>>() {
            });

            if (json == null || json.getCode() != 200) {
                return null;
            }

            return json.getResult();
        } catch (Exception e) {
            return null;
        }
    }

    private static String createUrl(String url, Map<String, String> args) {
        if (args == null) {
            return url;
        }

        url += "?";
        for (String key : args.keySet()) {
            url += key + "=" + args.get(key) + "&";
        }

        return url;
    }

    public interface IHttpRequestCallback {
        public abstract void onDataCallBack(Object data);
    }
}
